home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Lib / parse / aparse_norm.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  13.0 KB  |  616 lines

  1. /* aparse_norm.c: normalise an address folloing local synonyms */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Lib/parse/RCS/aparse_norm.c,v 6.0 1991/12/18 20:23:41 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Lib/parse/RCS/aparse_norm.c,v 6.0 1991/12/18 20:23:41 jpo Rel $
  9.  *
  10.  * $Log: aparse_norm.c,v $
  11.  * Revision 6.0  1991/12/18  20:23:41  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15. #include "util.h"
  16. #include "adr.h"
  17. #include "aparse.h"
  18. #include "alias.h"
  19.  
  20. extern char *loc_dom_site;
  21.  
  22. static int x400_norm(), x400_local_norm(), 
  23.     rfc822_norm(), rfc822_local_norm(),
  24.     convert_to_x400(), convert_to_rfc822();
  25.  
  26. int aparse_norm (ap)
  27. register Aparse_ptr ap;
  28. {
  29.     int    out_adr_type = ap->ad_type;
  30.  
  31.     if (ap->aliases) {
  32.         aparse_freeAliasList (ap->aliases);
  33.         ap->aliases = NULL;
  34.     }
  35.  
  36.     switch (ap->ad_type) {
  37.         case AD_X400_TYPE:
  38.         if (x400_norm(ap) != OK) 
  39.             return NOTOK;
  40.         if (ap->ad_type != out_adr_type
  41.             && convert_to_x400 (ap) != OK)
  42.             return NOTOK;
  43.         return OK;
  44.         
  45.         case AD_822_TYPE:
  46.         default:
  47.         if (rfc822_norm(ap) != OK)
  48.             return NOTOK;
  49.         if (ap->ad_type != out_adr_type
  50.             && convert_to_rfc822 (ap) != OK)
  51.             return NOTOK;
  52.         return OK;
  53.     }
  54. }
  55.  
  56. /*   */
  57.  
  58. static int x400_norm (ap)
  59. register Aparse_ptr ap;
  60. {
  61.     int    type;
  62.     char    *replace;
  63.     char    buf[BUFSIZ];
  64.  
  65.     if (ap->x400_str == NULLCP
  66.         && ap->orname->on_or == NULLOR)
  67.         return NOTOK;
  68.  
  69.     if (ap->orname->on_or == NULLOR) {
  70.         ap->orname->on_or = 
  71.             or_std2or(ap->x400_str);
  72.         ap->orname->on_or = or_default(ap->orname->on_or);
  73.     }
  74.         
  75.     
  76.     if (ap->x400_local) {
  77.         free(ap->x400_local);
  78.         ap->x400_local = NULLCP;
  79.     }
  80.     if (or_check (&(ap->orname->on_or),
  81.               buf, &type,
  82.               &(ap->local_hub_name),
  83.               &replace,
  84.               &(ap->lastMatch)) == NOTOK)
  85.         return NOTOK;
  86.     if (replace) free(replace);
  87.  
  88.     if (type == OR_ISLOCAL) {
  89.         ap->x400_local = strdup(buf);
  90.         return x400_local_norm (ap);
  91.     }
  92.     ap->ad_type = AD_X400_TYPE;
  93.     return OK;
  94. }
  95.  
  96. /*   */
  97.  
  98. static int x400_local_norm (ap)
  99. register Aparse_ptr ap;
  100. {
  101.     ALIAS alias_struct, *alp = &alias_struct;
  102.     OR_ptr    syn, tmp;
  103.     char    buf[BUFSIZ];
  104.  
  105.     if (ap->x400_local == NULLCP)
  106.         return NOTOK; /* ? */
  107.     if (ap->dont_use_aliases == TRUE) {
  108.         ap->ad_type = AD_X400_TYPE;
  109.         return OK;
  110.     }
  111.     if (tb_getalias (ap->x400_local,
  112.              alp, ap->local_hub_name) != OK
  113.         || alp->alias_type != ALIAS_SYNONYM) {
  114.         /* no synonym */
  115.         ap->ad_type = AD_X400_TYPE;
  116.         return OK;
  117.     }
  118.  
  119.     if (alp->alias_external == ALIAS_EXTERNAL) {
  120.         if (ap->internal == TRUE) {
  121.             /* don't follow */
  122.             ap->ad_type = AD_X400_TYPE;
  123.             return OK;
  124.         }
  125.         /* follow but don't use aliases table */
  126.         /* may still need to normalise */
  127.         ap->dont_use_aliases = TRUE;
  128.     }
  129.  
  130.     alias2adr (buf, alp, ap);
  131.  
  132.     if (aparse_inAliasList (buf, ap->aliases) == OK) {
  133.         if (alp->alias_external != ALIAS_EXTERNAL)
  134.             /* looping synonym */
  135.             return NOTOK;
  136.         /* ignore loops if external */
  137.     }else
  138.         aparse_addToAliasList (buf, &(ap->aliases));
  139.     
  140.     switch (alp->alias_ad_type) {
  141.         case AD_ANY_TYPE:
  142.         /* replace from *ptree to lastMatch -> or_prev */
  143.         /* with alp->alias_user */
  144.         
  145.         if ((syn = or_std2or(alp->alias_user)) == NULLOR)
  146.             return NOTOK;
  147.  
  148.         /* rmoove old stuff */
  149.         tmp = ap->lastMatch->or_next;
  150.         tmp->or_prev = NULLOR;
  151.         ap->lastMatch->or_next = NULLOR;
  152.         or_free(tmp);
  153.         
  154.         while (syn != NULLOR) {
  155.             tmp = syn -> or_next;
  156.             if (tmp != NULLOR) {
  157.                 syn -> or_next = NULLOR;
  158.                 tmp -> or_prev = NULLOR;
  159.             }
  160.  
  161.             if ((ap->orname->on_or = or_add (ap->orname->on_or,
  162.                              syn, TRUE)) == NULLOR)
  163.                 return NOTOK;
  164.             syn = tmp;
  165.         }
  166.         break;
  167.  
  168.         case AD_X400_TYPE:
  169.         /* completely replace old tree */
  170.         or_free (ap->orname->on_or);
  171.         if ((ap->orname->on_or = or_std2or(alp->alias_user)) == NULLOR)
  172.             return NOTOK;
  173.         ap->orname->on_or = or_default(ap->orname->on_or);
  174.         break;
  175.  
  176.         default:
  177.         /* 822 synonym */
  178.         aparse_rewindr822(ap);
  179.         ap->r822_str = strdup(alp->alias_user);
  180.         return rfc822_norm (ap);
  181.     }
  182.  
  183.     return x400_norm(ap);
  184. }
  185.  
  186. /*   */
  187.  
  188. AP_ptr merge_new (ap, ntree, nloc, ndom)
  189. AP_ptr    ap, ntree, nloc, ndom;
  190. {
  191.     AP_ptr    hdr, ix, nix = NULLAP, tmp;
  192.     int    cont = TRUE;
  193.     
  194.     hdr = ap_new(AP_COMMENT, "header");
  195.     hdr->ap_next = ap;
  196.     hdr->ap_ptrtype = AP_PTR_MORE;
  197.     ix = hdr;
  198.  
  199.     /* delete up to first mailbox */
  200.     while (ix->ap_next != NULL
  201.            && cont == TRUE) {
  202.         switch (ix -> ap_next -> ap_obtype) {
  203.             case AP_DOMAIN:
  204.             case AP_DOMAIN_LITERAL:
  205.             /* part of route */
  206.             ap_delete (ix);
  207.             break;
  208.                 
  209.             case AP_MAILBOX:
  210.             case AP_GENERIC_WORD:
  211.             /* reached mailbox */
  212.             cont = FALSE;
  213.             break;
  214.                 
  215.             case AP_COMMENT:
  216.             default:
  217.             /* preserve */
  218.             ix = ix->ap_next;
  219.             break;
  220.         }
  221.     }
  222.         
  223.     /* merge in ntree up to inclusive */
  224.     if (ntree) {
  225.         for (nix = ntree;
  226.              nix -> ap_next != NULLAP
  227.              && nix -> ap_next != nloc -> ap_next;
  228.              nix = nix -> ap_next)
  229.             continue;
  230.         if (nix) {
  231.             tmp = nix -> ap_next;
  232.             nix -> ap_next = NULLAP;
  233.         } else
  234.             tmp = NULLAP;
  235.             
  236.         ix = ap_sqinsert(ix,
  237.                  AP_PTR_MORE,
  238.                  ntree);
  239.         nix = tmp;
  240.     }
  241.  
  242.     cont = TRUE;
  243.     /* delete up to next domain */
  244.     while (ix->ap_next != NULL
  245.            && cont == TRUE) {
  246.         switch (ix -> ap_next -> ap_obtype) {
  247.             case AP_DOMAIN:
  248.             case AP_DOMAIN_LITERAL:
  249.             cont = FALSE;
  250.             break;
  251.                 
  252.             case AP_MAILBOX:
  253.             case AP_GENERIC_WORD:
  254.             ap_delete (ix);
  255.             break;
  256.                 
  257.             case AP_COMMENT:
  258.             default:
  259.             /* preserve */
  260.             ix = ix->ap_next;
  261.             break;
  262.         }
  263.     }
  264.         
  265.     /* merge in up to ndom inclusive */
  266.     if (nix) {
  267.         ntree = nix;
  268.         for (;
  269.              nix -> ap_next != NULLAP
  270.              && nix -> ap_next != ndom -> ap_next;
  271.              nix = nix -> ap_next)
  272.             continue;
  273.         if (nix) {
  274.             tmp = nix -> ap_next;
  275.             nix -> ap_next = NULLAP;
  276.         } else
  277.             tmp = NULLAP;
  278.         ix = ap_sqinsert(ix,
  279.                  AP_PTR_MORE,
  280.                  ntree);
  281.         nix = tmp;
  282.     } else
  283.         /* no local */
  284.         return NULLAP;
  285.         
  286.     /* delete remaining domains */
  287.     cont = TRUE;
  288.     while (ix->ap_next != NULLAP && cont == TRUE) {
  289.         switch (ix -> ap_next -> ap_obtype) {
  290.             case AP_DOMAIN:
  291.             case AP_DOMAIN_LITERAL:
  292.             case AP_MAILBOX:
  293.             case AP_GENERIC_WORD:
  294.             ap_delete(ix);
  295.             break;
  296.             case AP_COMMENT:
  297.             /* preserve */
  298.             ix = ix -> ap_next;
  299.             break;
  300.             default:
  301.             /* save end of names etc */
  302.             cont = FALSE;
  303.             break;
  304.         }
  305.     }
  306.         
  307.     if (nix)
  308.         ix = ap_sqinsert(ix,
  309.                  AP_PTR_MORE,
  310.                  nix);
  311.     ap = hdr -> ap_next;
  312.     ap_free(hdr);
  313.     return ap;
  314. }
  315.  
  316. #ifdef VAT
  317. static void db_check(name, loc, dom, route)
  318. AP_ptr    name,
  319.     loc,
  320.     dom, 
  321.     route;
  322. {
  323.     AP_ptr    ix = name;
  324.     
  325.     while (ix != NULLAP &&
  326.            ix != loc &&
  327.            ix != dom &&
  328.            ix != route) {
  329.         if ((ix -> ap_obtype == AP_PERSON_END
  330.              || ix -> ap_obtype == AP_PERSON_NAME
  331.              || ix -> ap_obtype == AP_PERSON_START)
  332.             && ix->ap_obvalue != NULLCP
  333.             && lexequ("Hardcastle-Kille", ix->ap_obvalue) == 0) {
  334.             AP_ptr    ix2, tmp = ap_s2t("Hardcastle(Hyphen)Kille");
  335.             
  336.             for (ix2 = tmp; ix2 != NULLAP; ix2 = ix2->ap_next) {
  337.                 if (ix2->ap_obtype != AP_COMMENT)
  338.                     ix2->ap_obtype = ix->ap_obtype;
  339.             }
  340.             (void) ap_sqinsert (ix, AP_PTR_MORE, tmp);
  341.             /* copy up and delete */
  342.             tmp = ix -> ap_next;
  343.             ix -> ap_obtype = tmp -> ap_obtype;
  344.             ix -> ap_ptrtype = tmp -> ap_ptrtype;
  345.             if (ix -> ap_obvalue) 
  346.                 free (ix->ap_obvalue);
  347.             ix -> ap_obvalue = tmp -> ap_obvalue;
  348.             tmp -> ap_obvalue = NULLCP;
  349.             ix -> ap_next = tmp -> ap_next;
  350.             tmp -> ap_next = NULLAP;
  351.             ap_free(tmp);
  352.         }
  353.         ix = ix -> ap_next;
  354.     }
  355. }
  356. #endif
  357.  
  358. static AP_ptr    get_next_route (ap, startfrom)
  359. register Aparse_ptr ap;
  360. AP_ptr        startfrom;
  361. {
  362.     AP_ptr    ret;
  363.     
  364.     if (startfrom == NULLAP)
  365.         return NULLAP;
  366.     
  367.     if (startfrom->ap_obtype == AP_DOMAIN
  368.         || startfrom->ap_obtype == AP_DOMAIN_LITERAL)
  369.         return startfrom;
  370.  
  371.     ret = startfrom;
  372.     for (;;) {
  373.         switch (ret->ap_ptrtype) {
  374.             case AP_PTR_MORE:
  375.             /* -- next is part of this address -- */
  376.             ret = ret -> ap_next;
  377.             if (ret == ap->ap_group ||
  378.                 ret == ap->ap_name ||
  379.                 ret == ap->ap_local ||
  380.                 ret == ap->ap_domain)
  381.                 return NULLAP;
  382.  
  383.             switch (ret -> ap_obtype) {
  384.                 case AP_DOMAIN_LITERAL:
  385.                 case AP_DOMAIN:
  386.                 return ret;
  387.                 default:
  388.                 break;
  389.             }
  390.             break;
  391.             default:
  392.             return NULLAP;
  393.         }
  394.     }
  395. }
  396.  
  397. static int rfc822_norm (ap)
  398. register Aparse_ptr ap;
  399. {
  400.     AP_ptr rout;
  401.  
  402.     if (ap->r822_str == NULLCP
  403.         && ap->ap_tree == NULLAP)
  404.         return NOTOK;
  405.  
  406.     if (ap->ap_tree == NULLAP) 
  407.         ap->ap_tree = ap_s2t(ap->r822_str);
  408.     
  409.     (void) ap_t2p (ap->ap_tree, &(ap->ap_group), 
  410.                &(ap->ap_name), &(ap->ap_local), 
  411.                &(ap->ap_domain), &(ap->ap_route));
  412.  
  413. #ifdef VAT
  414.     if ((getpid() % 10) == 2)
  415.         db_check (ap->ap_name, ap->ap_local,
  416.               ap->ap_domain, ap->ap_route);
  417. #endif
  418.  
  419.     if (ap->normalised == APARSE_NORM_ALL) {
  420.         /* normalise all domains */
  421.         rout = ap->ap_route;
  422.         while (rout &&
  423.                (rout = get_next_route(ap, rout)) != NULLAP) {
  424.             (void) rfc822_norm_dmn(rout, ap->dmnorder);
  425.             rout = rout->ap_next;
  426.         }
  427.         if (ap->ap_domain)
  428.             (void) rfc822_norm_dmn (ap->ap_domain, ap->dmnorder);
  429.         rout = get_next_route (ap, ap->ap_route);
  430.     } else {
  431.         /* normalise first domain */
  432.         if ((rout = get_next_route(ap, ap->ap_route)) != NULLAP)
  433.             (void) rfc822_norm_dmn (rout, ap->dmnorder);
  434.         else if (ap->ap_domain)
  435.             (void) rfc822_norm_dmn(ap->ap_domain, ap->dmnorder);
  436.             
  437.     }
  438.  
  439.     while (rout && rout->ap_islocal == TRUE) {
  440.         /* local so remove from route */
  441.         ap->ap_route = rout = get_next_route(ap, rout->ap_next);
  442.         if (rout && rout->ap_normalised != TRUE)
  443.             (void) rfc822_norm_dmn(rout, ap->dmnorder);
  444.     }
  445.  
  446.     if (rout == NULLAP) {
  447.         /* no route */
  448.         if (ap->ap_domain == NULLAP) {
  449.             /* no domain either so add default */
  450.             if (ap->ap_local == NULLAP)
  451.                 /* no local either so fail */
  452.                 return NOTOK;
  453.             for (rout = ap->ap_local;
  454.                  rout -> ap_next != NULLAP;
  455.                  rout = rout -> ap_next)
  456.                 continue;
  457.             (void) ap_append(rout, AP_DOMAIN, loc_dom_site);
  458.             ap->ap_domain = rout -> ap_next;
  459.             (void) rfc822_norm_dmn(ap->ap_domain, ap->dmnorder);
  460.         } else if (ap->ap_domain->ap_normalised != TRUE)
  461.             (void) rfc822_norm_dmn(ap->ap_domain, ap->dmnorder);
  462.         
  463.         if (ap->ap_domain->ap_islocal == TRUE) 
  464.             return rfc822_local_norm(ap);
  465.     }
  466.     ap->ad_type = AD_822_TYPE;
  467.     return OK;
  468. }
  469.  
  470. static int rfc822_local_norm(ap)
  471. register Aparse_ptr ap;
  472. {
  473.     ALIAS alias_struct, *alp = &alias_struct;
  474.     char    buf[BUFSIZ], *str;
  475.     AP_ptr    newtree, newgroup, newname, newloc, newdom, newroute;
  476.  
  477.     if (ap->r822_local) free(ap->r822_local);
  478.     ap->r822_local = ap_p2s_nc(NULLAP, NULLAP,
  479.                    ap->ap_local,
  480.                    NULLAP, NULLAP);
  481.  
  482.     if (ap->dont_use_aliases == TRUE) {
  483.         ap->ad_type = AD_822_TYPE;
  484.         return OK;
  485.     }
  486.  
  487.     if (tb_getalias(ap->r822_local, alp, ap->ap_domain->ap_localhub) != OK
  488.         || alp->alias_type != ALIAS_SYNONYM) {
  489.         /* no synonym */
  490.         ap->ad_type = AD_822_TYPE;
  491.         return OK;
  492.     }
  493.  
  494.     if (alp->alias_external == ALIAS_EXTERNAL) {
  495.         if (ap->internal == TRUE) {
  496.             /* don't follow */
  497.             ap->ad_type = AD_822_TYPE;
  498.             return OK;
  499.         }
  500.         /* follow but don't use aliases table */
  501.         /* may still need to normalise */
  502.         ap->dont_use_aliases = TRUE;
  503.     }
  504.  
  505.     alias2adr (buf, alp, ap);
  506.     
  507.     if (aparse_inAliasList (buf, ap->aliases) == OK) {
  508.         if (alp->alias_external != ALIAS_EXTERNAL)
  509.             /* looping synonym */
  510.             return NOTOK;
  511.         /* ignore lopps if external */
  512.     } else
  513.         aparse_addToAliasList (buf, &(ap->aliases));
  514.  
  515.     switch (alp->alias_ad_type) {
  516.         case AD_ANY_TYPE:
  517.         /* use existing domian but replace loc */
  518.         newloc = ap_s2t(alp->alias_user);
  519.         str = ap_p2s(NULLAP, NULLAP, newloc, ap->ap_domain, NULLAP);
  520.         ap_free(newloc);
  521.         break;
  522.  
  523.         case AD_822_TYPE:
  524.         /* replace all */
  525.         str = strdup(alp->alias_user);
  526.         break;
  527.         
  528.         default:
  529.         aparse_rewindx400(ap);
  530.         ap->x400_str = strdup(alp->alias_user);
  531.         return x400_norm(ap);
  532.     }
  533.     
  534.     newtree= ap_s2t(str);
  535.     (void) ap_t2p(newtree, &newgroup,
  536.               &newname, &newloc,
  537.               &newdom, &newroute);
  538.     ap->ap_tree = merge_new(ap->ap_tree, newtree, newloc, newdom);
  539.     
  540.     free(str);
  541.     (void) ap_t2p (ap->ap_tree, &(ap->ap_group), 
  542.                &(ap->ap_name), &(ap->ap_local), 
  543.                &(ap->ap_domain), &(ap->ap_route));
  544.  
  545.     if (ap->r822_str) free(ap->r822_str);
  546.     ap->r822_str = ap_p2s(ap->ap_group, ap->ap_name,
  547.                   ap->ap_local, ap->ap_domain,
  548.                   ap->ap_route);
  549.     return rfc822_norm (ap);
  550. }
  551.  
  552.     
  553. /*   */
  554.  
  555. extern char    or_error[];
  556.  
  557. static int convert_to_x400 (ap)
  558. register Aparse_ptr ap;
  559. {
  560.     char    tbuf[BUFSIZ];
  561.     OR_ptr or;
  562.  
  563.     if (ap -> r822_str == NULLCP)
  564.         return NOTOK;
  565.  
  566.     aparse_rewindx400(ap);
  567.  
  568.     if (or_rfc2or_aux (ap->r822_str,
  569.                &(ap->orname->on_or), 1) == NOTOK) {
  570.         or_free(ap->orname->on_or);
  571.         ap->orname->on_or = NULLOR;
  572.         PP_DBG(("convert_to_x400 failed (%s)", or_error));
  573.         return NOTOK;
  574.     }
  575.     
  576.     if ((or = or_default (ap->orname->on_or)) == NULLOR) {
  577.         PP_LOG (LLOG_EXCEPTIONS, ("or_default failed"));
  578.         return NOTOK;
  579.     }
  580.     ap -> orname -> on_or = or;
  581.  
  582.     or_or2std (ap->orname->on_or, tbuf, FALSE);
  583.     ap->x400_str = strdup(tbuf);
  584.     ap->ad_type = AD_X400_TYPE;
  585.  
  586.     return OK;
  587. }
  588.  
  589. /*   */
  590.  
  591. static int convert_to_rfc822 (ap)
  592. register Aparse_ptr ap;
  593. {
  594.     char    tbuf[BUFSIZ];
  595.  
  596.     if (ap->orname->on_or == NULLOR)
  597.         return NOTOK;
  598.  
  599.     aparse_rewindr822(ap);
  600.  
  601.     if (or_or2rfc (ap->orname->on_or, tbuf) == NOTOK) {
  602.         PP_DBG(("convert_to_rfc822 failed (%s)", or_error));
  603.         return NOTOK;
  604.     }
  605.  
  606.     ap->r822_str = strdup(tbuf);
  607.     ap->ap_tree = ap_s2t(ap->r822_str);
  608.     (void) ap_t2p (ap->ap_tree, &(ap->ap_group), 
  609.                &(ap->ap_name), &(ap->ap_local), 
  610.                &(ap->ap_domain), &(ap->ap_route));
  611.  
  612.     ap->ad_type = AD_822_TYPE;
  613.     
  614.     return OK;
  615. }
  616.